package org.zoomdev.zoom.dao;

import org.zoomdev.zoom.dao.impl.SimpleSelect;
import org.zoomdev.zoom.dao.impl.SqlConfig;
import org.zoomdev.zoom.dao.structs.ColumnMeta;
import org.zoomdev.zoom.dao.structs.TableMeta;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public abstract class Entity<T> implements ResultSetParser {

    protected final TableMeta tableMeta;
    protected final SqlDriver driver;
    protected final String table;
    protected final EntityField[] primaryKeys;

    protected final EntityField[] entityFields;
    protected AutoGenerateEntity autoGenerateEntity;

    public Entity(SqlDriver sqlDriver, TableMeta table,
                  EntityField[] primaryKeys,
                  EntityField[] entityFields) {
        this.driver = sqlDriver;
        this.table = table.getName();
        this.tableMeta = table;
        this.primaryKeys = primaryKeys;
        this.entityFields = entityFields;

    }


    public EntityField[] getEntityFields() {
        return entityFields;
    }


    public EntityField[] getPrimaryKeys() {
        return primaryKeys;
    }


    public abstract void buildSelect(SimpleSelect select, SqlConfig config);

    public abstract void buildDelete(SimpleSelect select, SqlConfig config);

    public abstract void buildInsert(T data, SimpleSelect select, SqlConfig config);

    public abstract void buildUpdate(T data, SimpleSelect select, SqlConfig config);

    public EntityField tryToFind(String field) {
        for (EntityField entityField : entityFields) {
            if (field.equalsIgnoreCase(entityField.getFieldName())) {
                return entityField;
            }
            if (field.equalsIgnoreCase(entityField.getColumnName())) {
                return entityField;
            }
            ColumnMeta meta = entityField.getColumn();
            if (meta != null) {
                if (field.equalsIgnoreCase(meta.getName())) {
                    return entityField;
                }
            }

        }
        return null;
    }

    public PreparedStatement prepareInsert(Connection connection, String sql) throws SQLException {
        // generate keys or next_val
        //"insert into xx values ()"
        if (autoGenerateEntity != null) {
            return autoGenerateEntity.prepareInsert(connection, sql);
        }
        return connection.prepareStatement(sql);
    }

    public void afterInsert(T data, PreparedStatement ps) throws SQLException {
        if (autoGenerateEntity != null) {
            autoGenerateEntity.afterInsert(data, ps);
        }
    }
}
